from django.http import HttpResponse
import _thread
import threading
import mysql.connector
import socket
import os
from . import finger_check
#import finger_check
import json

processing_website = {}
process_lock = threading.Lock()

state_error = r'{"state":"error"}'
state_processing = r'{"state":"processing"}'
state_none = r'{"state":"none"}'

debug_info = 'None'

def mainpage(request):
    resp = r'<html><head><meta http-equiv="Refresh" content="0;url=/html/index.html"></meta></head><body>' \
           r'<script language="javascript" type="text/javascript">' \
           r'//window.location.href="/html";' \
           r'</script>' \
           r'</body></html>'
    return HttpResponse(resp)


def ip_check(request):
    if request.method != 'GET' or 'website' not in request.GET:
        return HttpResponse(state_error)

    website = request.GET['website']
    host = website
    host = host[host.find("//") + 2:]
    if ("/" in host):
        host = host[:host.find("/")]

    try:
        ip = socket.gethostbyname(host)
    except Exception as error:
        return HttpResponse(state_error)


    return HttpResponse(r'{"state":"got","IP":"' + ip + r'"}')



#@csrf_protect
def fingerprint_check(request):

    global debug_info

    #不是POST请求
    if request.method != 'GET' or 'website' not in request.GET:
        return HttpResponse(state_error)

    website = request.GET['website']

    #返回上一次的错误信息
    if website == 'debug':
        return HttpResponse(debug_info)

    try:
        database_check_result = database_check(website)
    except Exception as e:
        debug_info = e.__str__() + r' >> database_check_result = database_check(website)'
        return HttpResponse(state_error)

    #数据库里有记录
    if database_check_result != -1:
        ip, fingerprint = database_check_result
        resp = r'{"state":"got","IP":"'
        resp += ip
        resp += r'", "result":'
        resp += fingerprint
        resp += r'}'

        return HttpResponse(resp)

    #网址在处理中或处理过程发生错误
    if website in processing_website:
        if processing_website[website] == 0:
            #网址正在被处理
            return HttpResponse(json.dumps({"state":"processing", "progress":finger_check.process_per}))
        else:
            #网址在处理的过程中发生错误
            processing_website.pop(website)
            return HttpResponse(state_error)

    #开启新线程后台处理
    _thread.start_new_thread(finger_find, (website,))
    return HttpResponse(state_none)




def data_query(request):

    global state_error
    global debug_info

    if request.method != 'GET' or 'get' not in request.GET:
        debug_info = 'no get'
        return HttpResponse(state_error)

    query_result = {}

    if request.GET['get'] == 'all_cache':
        try:
            query_result = get_all_cache()
        except Exception as e:
            debug_info = e.__str__()
            return HttpResponse(state_error)
        return HttpResponse(json.dumps(query_result))

    elif request.GET['get'] == 'all_cats':
        try:
            query_result = get_all_cats()
        except Exception as e:
            return HttpResponse(state_error)
        return HttpResponse(json.dumps(query_result))

    elif request.GET['get'] == 'each_tech':
        try:
            if 'cats' not in request.GET:
                return HttpResponse(state_error)

            cats = request.GET['cats']

            query_result = get_each_tech(cats)

        except Exception as e:
            debug_info = e.__str__()
            return HttpResponse(state_error)
        return HttpResponse(json.dumps(query_result))

    elif request.GET['get'] == 'each_website':
        try:
            if 'tech' not in request.GET:
                return HttpResponse(state_error)
            tech = request.GET['tech']

            query_result = get_each_website(tech)
        except Exception as e:
            debug_info = e.__str__()
            return HttpResponse(state_error)
        return HttpResponse(json.dumps(query_result))

    elif request.GET['get'] == 'fingerprint':
        try:
            if 'tech' not in request.GET:
                return HttpResponse(state_error)
            tech = request.GET['tech']

            query_result = get_tech_fingerprint(tech)
        except Exception as e:
            debug_info = e.__str__()
            return HttpResponse(state_error)
        return HttpResponse(json.dumps(query_result))

    return HttpResponse(state_error)



#######################################################################################

#检查数据库中是否有网址
def database_check(website):
    global debug_info
    try:
        cnx = mysql.connector.connect(user='root', database='gingko')
        cursor = cnx.cursor(dictionary=True)
        query = (r"select * from cache where Domain=%s")
        cursor.execute(query, (website,))
        query_result = cursor.fetchall()
        cnx.close()
        #print(query_result)
    except Exception as e:
        debug_info = e.__str__() + r'database_check(website)'
        return -1
    if len(query_result) == 0:
        return -1

    return (query_result[0]['IP'], query_result[0]['tag'])

#获取指纹信息
def finger_find(website):
    global debug_info
    #global processing_website
    #global process_lock

    #processing_website['thread'] = 1

    process_lock.acquire()
    processing_website[website] = 0
    process_lock.release()

    #processing_website['thread'] = 1.5

    try:
        finger_check.process_per = 0
        find_result = finger_check.web_finger_check(website)
    except Exception as e:
        debug_info = e.__str__() + r' >> finger_check.web_finger_check(website) '
        processing_website[website] = -1
        #processing_website['thread'] = e.__str__()
        return

    #processing_website['thread'] = 2
    #return

    host = website
    host = host[host.find("//") + 2:]
    if ("/" in host):
        host = host[:host.find("/")]

    try:
        ip = socket.gethostbyname(host)
    except Exception as error:
        processing_website[website] = -1
        debug_info = e.__str__() + r' >> ip = socket.gethostbyname(host)'
        return

    try:
        cnx = mysql.connector.connect(user='root', database='gingko')
        cursor = cnx.cursor(dictionary=True)
        query = (r"insert into cache values (%s, %s, %s)")

        find_result_json = json.dumps(find_result)

        cursor.execute(query, (website, ip, find_result_json))
        cnx.commit()
        cnx.close()
    except Exception as error:
        processing_website[website] = -1
        debug_info = e.__str__() + r' >> finger_find(website) -> save result'
        return
    #processing_website['thread'] = 3

    process_lock.acquire()
    processing_website.pop(website)
    process_lock.release()

    #processing_website['thread'] = 4

    return


#finger_find('https://www.cnblogs.com/aaronjs/p/4165049.html')


def get_all_cache():
    cnx = mysql.connector.connect(user='root', database='gingko')
    cursor = cnx.cursor(dictionary=True)
    query = (r"SELECT Domain, IP FROM cache")
    cursor.execute(query)
    query_result = cursor.fetchall()

    result = {}

    for i1 in query_result:
        result[i1['Domain']] = i1['IP']
    return result

def get_all_cats():
    cnx = mysql.connector.connect(user='root', database='gingko')
    cursor = cnx.cursor(dictionary=True)
    query = (r"SELECT * FROM cats")
    cursor.execute(query)
    query_result = cursor.fetchall()

    result = {'cats':[]}

    for i1 in query_result:
        result['cats'].append(i1['Name'])
    return result

def get_each_tech(cat):
    cnx = mysql.connector.connect(user='root', database='gingko')
    cursor = cnx.cursor(dictionary=True)
    query = (r"SELECT name, cats FROM data")
    cursor.execute(query)
    query_data_result = cursor.fetchall()

    query = (r'SELECT Cat FROM cats WHERE Name=%s')
    cursor.execute(query, (cat, ))
    query_cats_result = cursor.fetchall()

    if len(query_cats_result) == 0:
        return {'techs':[]}

    cats_id = query_cats_result[0]['Cat']
    result = {'techs': []}

    for i1 in query_data_result:
        if str(cats_id) in json.loads(i1['cats']):
            result['techs'].append(i1['name'])
    return result

def get_each_website(tech):
    cnx = mysql.connector.connect(user='root', database='gingko')
    cursor = cnx.cursor(dictionary=True)
    query = (r"SELECT * FROM cache")
    cursor.execute(query)
    query_result = cursor.fetchall()

    result = {'websites':[]}

    for i1 in query_result:
        #print(i1['tag'])
        fingerprint_result = json.loads(i1['tag'])
        for i2 in fingerprint_result:
            if tech in fingerprint_result[i2]:
                result['websites'].append(i1['Domain'])
                break
    return result

def get_tech_fingerprint(tech):
    cnx = mysql.connector.connect(user='root', database='gingko')
    cursor = cnx.cursor(dictionary=True)
    query = (r"SELECT * FROM data WHERE name=%s")
    cursor.execute(query, (tech,))
    query_result = cursor.fetchall()
    result = {'fingerprint': {}}
    if len(query_result) == 0:
        return result

    for i1 in query_result[0]:
        if i1 == 'name' or i1 == 'cats' or i1 == 'excludes' or query_result[0][i1] == None:
            continue
        result['fingerprint'][i1] = json.loads(query_result[0][i1])

    return result


#print(get_each_website('Tengine'))